package cn.itcast.bos.service.base.impl;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder.Operator;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.itcast.bos.dao.index.elasticsearch.WayBillIndexRepository;
import cn.itcast.bos.domain.take_delivary.WayBill;
import cn.itcast.bos.web.Dao.teke_delivary.WayBillRepository;
import cn.itcast.bos.web.Dao.teke_delivary.WayBillService;

@Service
@Transactional // 开启事务管理
public class WayBillServiceimpl implements WayBillService {

	// 注入Repository
	@Autowired
	private WayBillRepository wayBillRepository;

	// 注入WayBillIndexReposiitory
	@Autowired
	private WayBillIndexRepository wayBillIndexRepository;

	@Override
	public void save(WayBill waybill) {
		// 判断运单号是否存在
		WayBill persistWayBill = wayBillRepository.findByWayBillNum(waybill.getWayBillNum());
		// 对运单号进行判断 是否不存在 并且判断 运单ID 是否存在 ///避免空指针异常
		if (persistWayBill == null || persistWayBill.getId() == null) {

			// 如果运单不存在
			wayBillRepository.save(waybill);
			// 保存索引
			wayBillIndexRepository.save(waybill);

		} else {
			// 运单存在
			try {
				Integer id = persistWayBill.getId(); // 运单存在 在做什么？？
				BeanUtils.copyProperties(persistWayBill, waybill); // 在做什么？？
				persistWayBill.setId(id); // 在做什么/?
				// 在运单号存在的情况下 保存索引
				wayBillIndexRepository.save(persistWayBill);

			} catch (Exception e) {
				e.printStackTrace();
				// throw new RuntimeException(e.getMessage()); // 这是在做什么？？ -----
				// 貌似是 抛出异常信息
			}
		}

	}

	// 进行运单的无条件查询
	@Override
	public Page<WayBill> findPageData(WayBill waybill, Pageable pageable) {
		// 判断WatBill 中 条件是否存在 也就是判断 条件搜索框中的条件是否匹配
		if (StringUtils.isBlank(waybill.getWayBillNum()) && StringUtils.isBlank(waybill.getSendAddress())
				&& StringUtils.isBlank(waybill.getRecAddress()) && StringUtils.isBlank(waybill.getSendProNum())
				&& (waybill.getSignStatus() == null || waybill.getSignStatus() == 0)) {
			// 无条件查询
			return wayBillRepository.findAll(pageable);
		} else {
			// 待条件查询
			// must 条件必须成立 and
			// must 条件必须不成立 not
			// should 条件可以成立 or
			BoolQueryBuilder query = new BoolQueryBuilder(); // 布尔查询 多条件组合查询
			// 向组合查询对象 添加条件
			if (StringUtils.isNoneBlank(waybill.getWayBillNum())) {
				// 运单号查询
				QueryBuilder termQuery = new TermQueryBuilder("wayBillNum", waybill.getWayBillNum());
				query.must(termQuery);
			}
			/// 发货地查询
			if (StringUtils.isNoneBlank(waybill.getSendAddress())) {
				// 发货地址 模糊查询
				// 情况一： 输入 北 是查询词条一部分 使用模糊匹配词条查询
				QueryBuilder wildcardQiery = new WildcardQueryBuilder("sendAddress",
						"*" + waybill.getSendAddress() + "*");
				// 情况二 ： 输入："北京市海淀区" 是多个词条组合 进行分词后 每个词条匹配查询
				QueryBuilder queryStringBuilder = new QueryStringQueryBuilder(waybill.getSendAddress())
						.field("sendAddress").defaultOperator(Operator.AND);
				// 两种情况 取 or 关系
				BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
				boolQueryBuilder.should(wildcardQiery);
				boolQueryBuilder.should(queryStringBuilder);

				query.must(wildcardQiery);
			}
			if (StringUtils.isNoneBlank(waybill.getRecAddress())) {
				// 进行收货地址的模糊查询
				// 第一种情况： 输入 ’北‘ 是查询词条一部分 使用模糊匹配词条查询
				QueryBuilder wildcardQiery = new WildcardQueryBuilder("recAddress",
						"*" + waybill.getRecAddress() + "*");
				// 第二种 : 输入 北京市朝阳区 是查询 多个词条组合 进行分词后 每个词条破匹配查询
				// QueryBuilder builder = new
				// QueryStringQueryBuilder(waybill.getRecAddress()).field("recSend").defaultOperator(Operator.AND);
				QueryBuilder stringQueryBuilder = new QueryStringQueryBuilder(waybill.getSendAddress())
						.field("sendAddress").defaultOperator(Operator.AND);

				// 将两种情况进行组合
				BoolQueryBuilder boolquery = new BoolQueryBuilder();
				boolquery.should(wildcardQiery);
				boolquery.should(stringQueryBuilder);
				query.filter(boolquery);
			}
			if (StringUtils.isNoneBlank(waybill.getSendProNum())) {
				// 速运类型 等值查询
				QueryBuilder termQuery = new WildcardQueryBuilder("sendProNum", waybill.getSendProNum());
				query.must(termQuery);
			}
			if (StringUtils.isNoneBlank(waybill.getSendProNum())) {
				// 速运类型 等值查询
				QueryBuilder termQuery = new WildcardQueryBuilder("sendProNum", waybill.getSendProNum());
				query.must(termQuery);
			}

			// 签收状态查询
			if (waybill.getSignStatus() != null && waybill.getSignStatus() != 0) {
				// 签收状态
				QueryBuilder termQuery = new TermQueryBuilder("signStatus", waybill.getSignStatus());
				query.must(termQuery);
			}
			// 进行 ？？？的创建
			SearchQuery searchQuery = new NativeSearchQuery(query);
			searchQuery.setPageable(pageable); // 分页效果 实现
			// 有条件查询 查询索引库
			return wayBillIndexRepository.search(searchQuery);
		}
	}

	// 进行快单的查询
	@Override
	public WayBill findByWayBillNum(String wayBillNum) {

		return wayBillRepository.findByWayBillNum(wayBillNum);
	}

}
